/*********************************************************************************************************
Class Name: NMRCanvasController 
* Author: Accenture 
* Date: 28-Feb-2012  
* Requirement/Project Name: NMR 
* Description: Controller class invoked when "Create Opportunity - Launch AdSell" lead button is clicked.
*              Used for invoking the getRepCanvass and createShellCustomer webservices. Also used for converting 
*              lead to opportunity and account.       
*********************************************************************************************************/

public without sharing class NMRCanvasController {
    
    Public String canvasSelected{get; set;}
    Public Boolean showError;
    Public String errorMessage;
    Public Lead singleLead = new Lead();
    private AppEndPoints__c endPoint = AppEndPoints__c.getInstance();
    
    private Map<String, String> canvassIssueMap = new Map<String, String>();
    
    //constructor - retrieves the lead from the id passed in the URL
    public NMRCanvasController(ApexPages.StandardController controller) {          
        this.singleLead =  (Lead)controller.getRecord();
    }    
    
    /**
    * Method used to invoke the getRepCanvass 'GET' webservice call.
    * It adds the Canvass Code and Name returned from the webservice call 
    * into a select option list and returns them to the VF page to be displayed.
    */       
    public List<SelectOption> getCanvasses(){
         List<SelectOption> canvassOptions = new List<SelectOption>();
         String canvassCode = '';
         
         HttpRequest req= new HttpRequest();       
         req.setMethod('GET');    
         req.setEndpoint(endPoint.CWS_End_URL__c + 'CwsProxy.svc/GetRepCanvass?attuid=' + singleLead.ATTUID__c); 
         req.setTimeout(60000);      
     
         canvassOptions.add(new SelectOption('','- None -'));
         try{        
              Http http = new Http();    
              HttpResponse res= http.send(req);
                System.debug(res.getBody());//require this debug for test enviornments
              if(res.getStatusCode() == 200){//successfull call
                  Dom.Document resDoc = res.getBodyDocument();
                  Dom.XMLNode repCanvass = resDoc.getRootElement();
                  Dom.XMLNode data = repCanvass.getChildElement('DATA', null);
                  if('S'.equals(data.getChildElement('Status', null).getText()))
                  {//Status = 'S' signifies success
                      for(Dom.XmlNode dataChild : data.getChildElements()) 
                      {
                          if('CanvassList'.equals(dataChild.getName())){
                              canvassCode = dataChild.getChildElement('CanvassCode', null).getText();
                              canvassOptions.add(new SelectOption(canvassCode, 
                                  dataChild.getChildElement('CanvassName', null).getText()));
                              canvassIssueMap.put(canvassCode, dataChild.getChildElement('CanvassIssue', null).getText());                              
                          } 
                      } 
                  }           
              }
          }catch(CalloutException e){       
             system.debug('Exception during canvass http call. Error message: '+e.getMessage());
         }catch(Exception e){
             system.debug('Unable to handle data while retreiving canvasses. Error message:' + e.getMessage());
         }
         return canvassOptions;
    
    }
    
    
    /**
    * Method used to make the NewShellCustomer and AssignCustomer 'POST' webservice call.
    * It creates a Shell cusomter in CSS and assignes the Rep as the owner.
    * Customer Id returned by NewShellCustomer is used to launch AdSell. 
    * Account Id used to reload the parent page. 
    */
    public PageReference createCustomerId(){
         PageReference pageRef;
         String customerId = '';
         if(NMRUtil.isEmpty(canvasSelected)){
             ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Please select a Canvass')); 
             return pageRef;
         }else{
                        
             customerId = createAssignShellCustomer();
                 
             if(showError==false){
                  Id accId = createAccandOpp(customerId);
                  pageRef = new PageReference('/apex/NMRShellCustomerLoad?CustId='+ customerId +'&PageId=' + accId);
                  pageRef.setRedirect(true);
                      
             }
             else{
                  pageRef = new PageReference('/apex/NMRAdsellErrorPage?error='+errorMessage);
             }
                  
             return pageRef;
        }
    }
    
    /**
    * Method used to make the CreateAndAssignShellCustomer 'POST' webservice call.
    * It creates a Shell cusomter in CSS and returns the customer id. It also assigns the shell customer to the Rep.
    */
    private String createAssignShellCustomer(){
        String customerId = '';
        String street = '';
        String state = ''; 
        String company = '';
        String city = '';
        String zip = '';
        String headingCode = '';
        String message = '';
        Integer checkEditsIndex = -1;
         
        if(!NMRUtil.isEmpty(singleLead.Street))
            street = EncodingUtil.urlEncode(singleLead.Street.trim(),'UTF-8');
        
        if(!NMRUtil.isEmpty(singleLead.City))
            city = EncodingUtil.urlEncode(singleLead.City.trim(),'UTF-8');
            
        if(!NMRUtil.isEmpty(singleLead.State))
            state = EncodingUtil.urlEncode(singleLead.State.trim(),'UTF-8');
            
        if(!NMRUtil.isEmpty(singleLead.Company))
            company = EncodingUtil.urlEncode(singleLead.Company.trim(),'UTF-8');
            
        if(!NMRUtil.isEmpty(singleLead.PostalCode))
            zip = EncodingUtil.urlEncode(singleLead.PostalCode.trim(),'UTF-8');
            
        String canvassIssue = canvassIssueMap.get(canvasSelected);
       
        if(!NMRUtil.isEmpty(singleLead.Primary_Heading__c)){
            List<Cate__c> headingList = [Select Id, Name, YP_Cat__c from Cate__c where Lead__c =: singleLead.Id and Description__c =: singleLead.Primary_Heading__c limit 1];
            if(headingList.size()>0)
                headingCode = '&heading=' + headingList[0].YP_Cat__c;
        }

        
        String body = 'sfdcAccountId=&state=' + state + '&custName=' + company + '&phoneNumber=' + singleLead.CleanPhone__c + '&custAddrStreet=' + street + '&custAddrCity=' + city + '&custAddrState=' + state + '&custAddrZip=' + zip + headingCode + '&repId=' + singleLead.ATTUID__c + '&canvassCode=' + canvasSelected + '&canvassIssue=' + canvassIssue + '&segment=&channel=';
        
        HttpRequest req= new HttpRequest();       
        req.setMethod('POST');           
        req.setEndpoint(endPoint.CWS_End_URL__c + 'CwsProxy.svc/CreateAndAssignShellCustomer?' + body); 
        req.setHeader('Content-Length','1024');
        req.setBody(body); 
        req.setTimeout(60000);      
        req.setCompressed(true);
        try{        
            Http http = new Http();    
            HttpResponse res= http.send(req);
            system.debug(res.getBody());//require this debug for test enviornments
            if(res.getStatusCode() == 200){ //success response    
                showError = false;
                Dom.XMLNode assignStatus;
                Dom.XMLNode assignData;
                Dom.Document resDoc = res.getBodyDocument();
                Dom.XMLNode rootElem = resDoc.getRootElement();
                
                //createShellCustOutput
                Dom.XMLNode shellCustOutput = rootElem.getChildElement('NewShellCustomerOutput', null);
                Dom.XMLNode shellData = shellCustOutput.getChildElement('DATA', null);
                Dom.XMLNode shellStatus = shellData.getChildElement('Status', null);
                
                //assignShellOutput
                if('S'.equalsIgnoreCase(shellStatus.getText())){
                    Dom.XMLNode custAssignOutput = rootElem.getChildElement('CustomerAssignmentOutput', null);
                    assignData = custAssignOutput.getChildElement('DATA', null);
                    assignStatus = assignData.getChildElement('Status', null);
                }                
                
                if('S'.equalsIgnoreCase(shellStatus.getText()) && 'S'.equalsIgnoreCase(assignStatus.getText()))
                {
                    Dom.XMLNode custData = shellData.getChildElement('CustomerData', null);
                    customerId = custData.getChildElement('CustomerId', null).getText();           
                }
                else{  
                   showError = True;
                   Dom.XMLNode errors;
                   if(!('S'.equalsIgnoreCase(shellStatus.getText())))
                       errors = shellData.getChildElement('Errors', null);
                   else
                       errors = assignData.getChildElement('Errors', null);    
                       
                   Dom.XMLNode error = errors.getChildElement('Error', null);
                   errorMessage = error.getChildElement('ErrorCode', null).getText();
                   message = error.getChildElement('Message', null).getText();
                   checkEditsIndex = message.lastIndexOf('ChecksandEditsError with Message:');
                   if(!NMRUtil.isEmpty(message) && message.contains('Record not found in CANVASS_SEGMENT table for canvass-code'))
                       errorMessage = 'You do not have access to create a Shell Customer for this Zip';
                   else if(checkEditsIndex != -1 && (checkEditsIndex + 33) <= (message.length() - 1))
                       errorMessage = message.subString(checkEditsIndex + 33);       
                       
                }          
            }
            else{ // error response
                showError = True;
                errorMessage = 'Error Code: ' + res.getStatusCode() + '. Error Message: ' + res.getStatus();
            }
                     
        }catch(CalloutException e){       
            system.debug('Exception during create and assign shell customer http call. Error message: '+e.getMessage());
            showError = True;
            errorMessage = 'Exception during create and assign shell customer http call. Error message: ' + e.getMessage();
        }catch(Exception e){
            system.debug('Unable to handle data while creating and assigning shell customer. Error message:' + e.getMessage());
            showError = True;
            errorMessage = 'Unable to handle data while creating and assigning shell customer. Error message: ' + e.getMessage();
        }
         
        return customerId;
        
    }
 
    
    /**
    * Method used to make update the Customer ID in lead and send it for conversion.
    * It creates a Shell cusomter in CSS and returns the customer id.
    */    
    public Id createAccandOpp(string custId){

        if(!NMRUtil.isEmpty(custId))
            singleLead.Customer_Id__c = custId;
    
        singleLead.NMR_Convert_Lead__c = true;
        
        if(NMRUtil.isEmpty(singleLead.ownerId) || String.valueOf(singleLead.ownerId).startsWith('OOG'))
            singleLead.ownerId = UserInfo.getUserId();
        
        try{
            update singleLead;
        } catch(DMLException e) {
            system.debug('Unable to update Lead. Error message:' + e.getMessage());    
        }
  
        return NMRCreateOpportunity.convertLead(singleLead);    
    }
    
    
    /**
    * Test Method
    */
    @isTest(SeeAllData=true)
    static void NMRCanvasControllerTest() {
        
        test.startTest();
        Lead lead = new Lead(lastName = 'Test Lead',recordtypeid=RecordTypeHelper.GetRecordTypeID('Lead', 'NMR Lead'),phone='9992995646',Company='testcomp1',Status='New',LeadSource ='AdStore', ATTUID__c = 'vc1987', Street='4th Lane', City='San Francisco', State='CA', Primary_Heading__c='Test');
        insert lead;
        
        Cate__c heading = new Cate__c(Description__c='Test', YP_Cat__c='8008001',Lead__c=lead.Id);
        insert heading;
        
        PageReference pageRef = Page.NMRCreateShellCustomer;
        ApexPages.StandardController sc = new ApexPages.standardController(lead);
        pageRef.getParameters().put('id', lead.Id);
        NMRCanvasController canvassController = new NMRCanvasController(sc);
        Test.setCurrentPage(pageRef);

        canvassController.getCanvasses();
        canvassController.canvasSelected = 'Box';
        canvassController.createCustomerId();
        canvassController.createAccandOpp('123456');
            
        test.stopTest();
    }

}